home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / tcp / amitcp / amitcp-src-22.lha / AmiTCP-2.2 / src / appl / napsaterm / emulate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-07  |  21.5 KB  |  958 lines

  1. /* emulate.c  -- key parsing for vt102/vt52/h19/etc  emulation
  2.  *
  3.  * (C) Copyright 1988, 1989 Chris Newman
  4.  * All Rights Reserved
  5.  * Permission is granted ot copy, modify, and use this as long
  6.  * as this notice remains intact.  This is a nifty program.
  7.  * 
  8.  * Doug's contribution: it
  9.  * "What do you mean? The implementation of scroll bars is trivial."
  10.  *
  11.  * $Author: ppessi $ $Revision: 1.3 $ $Date: 1993/03/29 07:49:14 $
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include "nifty.h"
  16. #include "display.h"
  17.  
  18. /* import bell routines from beep.c or private display module */
  19. extern void audiobell();
  20.  
  21. /* import from misc.c */
  22. extern char *itos();
  23.  
  24. /* import from main routines */
  25. extern int write_to_tty();
  26.  
  27. /* import from display routines */
  28. extern int dsstyle();
  29. extern void dskeyboard();
  30.  
  31. #define    MAXTERMBUF  300
  32. #define    MAXESCBUF   20
  33. #define    MAXARG        7
  34.  
  35. #define VT100ATTRIBS  "\033[?1;2c"
  36.  
  37. /* these are program global variables */
  38. int emulation =    EMU_VT102;        /* current terminal emulation */
  39. int vt100_yucky_wrap_mode = 0;        /* vt100 wrap flag */
  40. int ansi_LNM = 0;            /* line feed/new line mode */
  41. int bell_type =    1;            /* 0 = norm, 1 = visual, 2 = audio, 3 = both */
  42. int pass8=1;                            /* 0 = strip 8th bit, 1 = pass 8th bit */
  43. /* these are local to this module */
  44. int savecurset = 0, saveG[2] = {0, 1};    /* area to save params */
  45. int esc_mode;                /* current escape mode */
  46. int private = 0;            /* private terminal modes -- 0, 1 = DEC, 2 = H19 */
  47. int curarg, arg[MAXARG+1];        /* ANSI code arguments */
  48. int curset = 0;                /* current VT100 character set */
  49. int G[2] = {0, 1};            /* settings for 2 VT100 sets */
  50. int sendgarbage    = 3;            /* if 2, terminal reports may be sent at times */
  51.  
  52. #if 0
  53. static char *termtype = "TERM=vt102";
  54. static char *termcap = "TERMCAP=dy|vt102|vt-102|wm|dec vt102:co#80:li#24:bw:am:xn:\
  55. \n\t:so=\\E[7m:se=\\E[27m:us=\\E[4m:ue=\\E[24m:ms:as=\\E)0^N:ae=\\E(B^O:\
  56. \n\t:md=\\E[1m:mr=\\E[7m:mb=\\E[5m:mt=\\E[3m:mk=\\E[8m:me=\\E[m:bc=^H:\
  57. \n\t:do=\\E[B:up=\\E[A:le=^H:nd=\\E[C:UP=\\E[%dA:DO=\\E[%dB:RI=\\E%dC:LE=\\E[%dD:\
  58. \n\t:cl=\\E[H\\E[2J:ho=\\E[H:cm=\\E[%i%d;%dH:cs=\\E[%i%d;%dr:IC=\\E[%d@:\
  59. \n\t:ce=\\E[K:cd=\\E[J:dc=\\E[P:DC=\\E[%dP:al=\\E[L:dl=\\E[M:rs=\\Ec:\
  60. \n\t:sc=\\E7:rc=\\E8:sf=\\ED:sr=\\EM:vb=\\EQ:AL=\\E[%dL:DL=\\E[%dM:\
  61. \n\t:im=\\E[4h:ei=\\E[4l:mi:km:ta=^I:";
  62. static char *h19termtype = "TERM=h19";
  63. static char *h19termcap = "TERMCAP=kb|h19|heath|zenith|z19|wm|heathkit h19:co#80:li#24:\
  64. \n\t:cr=^M:nl=^J:al=\\EL:am:le=^H:bs:cd=\\EJ:ce=\\EK:cl=\\EE:\
  65. \n\t:cm=\\EY%+ %+ :dc=\\EN:ei=\\EO:im=\\E@:mi:ta=^I:\
  66. \n\t:dl=\\EM:do=\\EB:ho=\\EH:mi:nd=\\EC:as=\\EF:ae=\\EG:ms:pt:sr=\\EI:\
  67. \n\t:se=\\Eq:so=\\Ep:up=\\EA:vs=\\Ex4:ve=\\Ey4:km:";
  68. static char *vt52termtype = "TERM=vt52";
  69. static char *vt52termcap = "TERMCAP=dw|vt52|vt-52|wm|dec vt52:\
  70. \n\t:do=^J:le=^H:bs:cd=\\EJ:ce=\\EK:cl=\\EH\\EJ:cm=\\EY%+ %+ :co#80:li#24:\
  71. \n\t:nd=\\EC:pt:sr=\\EI:up=\\EA:kb=^H:km:";
  72.  
  73. #endif
  74. /***** look at the code for ts and fs and ds and is -- status line *****
  75.  */
  76.  
  77. /* terminal capabilites:
  78.  * co# -- number of columns, set on startup
  79.  * li# -- number of lines, set on startup
  80.  * bw -- cursor left is backspace
  81.  * am, xn -- Terminal wraps at 80 columns, only if two graphic characters are sent.
  82.  * mi,ms -- safe to move in insert/standout mode
  83.  * so,se -- standout (inverse video) characters start/end
  84.  * us,ue -- underline characters start/end
  85.  * as,ae -- enter/exit alternate character set
  86.  * md,mr,mb -- make dark (bold), make reverse (inverse), make blink (flash)
  87.  * mt,mk,me -- make iTalic, make blank, make styles end
  88.  * do,le, bc -- cursor down, cursor left, backspace character (same as cursor left).
  89.  * up,nd -- cursor up, cursor right (non-destructive space)
  90.  * UP, DO, RI, LE -- move up/down/right/left n characters
  91.  * cl,ho -- clear screen, home cursor
  92.  * ce,cd -- clear to end of line/display
  93.  * sc,rc -- save/recall cursor position
  94.  * cs -- change scrolling region
  95.  * rs -- reset terminal
  96.  * dc,DC -- delete character(s)
  97.  * IC -- insert character(s)
  98.  * al,AL,dl,DL -- add line(s), delete line(s)
  99.  * im, ei -- insert mode, end insert mode
  100.  * vs, ve -- very visual cursor, normal visual cursor
  101.  * sf, sr -- scroll forward/reverse.  Cursor must be at bottom/top of screen.
  102.  * vb -- visual bell
  103.  * cm -- cursor move
  104.  * ta,cr,nl -- tab/carriage return/new line
  105.  */
  106.  
  107. /* different terminal modes
  108.  */
  109. void terminalMode(num, private, on)
  110. int num, private, on;
  111. {
  112.     switch (private) {
  113.     case 0:    /* standard ansi modes */
  114.         switch (num) {
  115.         case 4:
  116.             dsfunction(on ? INSERT_ON : INSERT_OFF);
  117.             break;
  118.  
  119.         case 20:
  120.             ansi_LNM = on;
  121.             break;
  122.         }
  123.         break;
  124.  
  125.     case 1: /* vt100 private modes */
  126.         /* unimplemented modes:
  127.          * 3 - 80/132 column mode
  128.          * 4 - soft/jump scroll
  129.          */
  130.         switch (num) {
  131.         case 1:
  132.             dskeyboard(DS_KEYPADAPPMODE, on);
  133.             break;
  134.  
  135.         case 2:
  136.             if (!on)
  137.             emulation = EMU_VT52;
  138.             break;
  139.  
  140.         case 5:
  141.             dsinvert(on ? INVERT_ON : INVERT_OFF);
  142.             break;
  143.                 
  144.         case 6:
  145.             dsfunction(on ? ORIGIN_ON : ORIGIN_OFF);
  146.             break;
  147.  
  148.         case 7:
  149.             dsfunction(on ? WRAP_ON : WRAP_OFF);
  150.             break;
  151.  
  152.         case 8:
  153.             dskeyboard(DS_AUTOREPEAT, on);
  154.             break;
  155.         }
  156.         break;
  157.  
  158.     case 2: /* h19 private modes */
  159.         /* modes not implemented:
  160.          * 1 - 25th line status (on -> enabled)
  161.          * 3 - hold screen mode
  162.          * 8 - auto linefeed on CR
  163.          * 9 - auto CR on linefeed
  164.          */
  165.         switch (num) {
  166.         case 2:
  167.             dskeyboard(DS_KEYCLICK, on ? 0 : 1);
  168.             break;
  169.  
  170.         case 4:
  171.             dsfunction(on ? BLOCK_CURSOR : UNDERLINE_CURSOR);
  172.             break;
  173.             
  174.         case 5:
  175.             dsfunction(on ? INVISIBLE_CURSOR : VISIBLE_CURSOR);
  176.             break;
  177.  
  178.         case 6:
  179.             dskeyboard(DS_KEYPADMODE, on ? KEYPAD_H19S : KEYPAD_H19);
  180.             break;
  181.  
  182.         case 7:
  183.             dskeyboard(DS_KEYPADAPPMODE, on);
  184.             break;
  185.         }
  186.         break;
  187.     }
  188. }
  189.  
  190. /* handle escape sequences
  191.  */
  192. int decode_escapes(c)
  193. char    c;
  194. {
  195.     int i, x, y;
  196.     
  197.     switch (esc_mode) {
  198.     case 1: /* escape key just pressed */
  199.         switch (c) {
  200.         case '[': /* ANSI sequence prefix */
  201.             for (i=0; i<=MAXARG; i++)
  202.             arg[i]=0;
  203.             esc_mode = 2;
  204.             private = 0;
  205.             return (0);
  206.  
  207.         case '#': /* DEC Private line width modes */
  208.             esc_mode = 3;
  209.             return (0);
  210.  
  211.         case '(': /* SCS: select character set -- for G[0] set */
  212.             esc_mode = 4;
  213.             return (0);
  214.  
  215.         case ')': /* SCS: select character set -- for G[1] set */
  216.             esc_mode = 5;
  217.             return (0);
  218.  
  219.         case 'D': /* IND (index): cursor down with scroll forward */
  220.             dscursormove(INDEX,0);
  221.             break;
  222.  
  223.         case 'E': /* NEL (next line): proper return */
  224.             dscursormove(NEXT_LINE,1);
  225.             break;
  226.  
  227.         case 'H': /* HTS horizontal tabulation set */
  228.             dsfunction(SET_TAB);
  229.             break;
  230.  
  231.         case 'M': /* RI (reverse index): cursor up with scroll reverse */
  232.             dscursormove(REVERSE_INDEX,0);
  233.             break;
  234.             
  235.         case 'Q': /* visual bell VT220 */
  236.             dsinvert(VISUAL_BELL);
  237.             break;
  238.  
  239.         case 'Z': /* DECID identify terminal */
  240.             (void) write_to_tty(VT100ATTRIBS,7);
  241.             break;
  242.  
  243.         case '7': /* DECSC save cursor position (DEC private) */
  244.             dscursormove(SAVE_CURSOR,0);
  245.             savecurset = curset;
  246.             saveG[0] = G[0];
  247.             saveG[1] = G[1];
  248.             break;
  249.  
  250.         case '8': /* DECRC restore cursor position (DEC private) */
  251.             dscursormove(RESTORE_CURSOR,0);
  252.             curset = savecurset;
  253.             G[0]=saveG[0];
  254.             G[1]=saveG[1];
  255.             break;
  256.  
  257.         case 'c': /* RIS reset to initial state */
  258.             dsfunction(RESET_DISPLAY);
  259.             break;
  260.         }
  261.         break;
  262.  
  263.     case 2: /* escape [ foo character */
  264.         switch (c) {
  265.         case ISDIGIT:
  266.             arg[curarg] *= 10;
  267.             arg[curarg] += c-'0';
  268.             return (0);
  269.  
  270.         case '?':
  271.             private = 1;
  272.             return (0);
  273.  
  274.         case '>':
  275.             private = 2;
  276.             return (0);
  277.             
  278.         case ';': /* get next parameter */
  279.             if (curarg < MAXARG)
  280.             arg[++curarg]=0;
  281.             return (0);
  282.  
  283.         case 'A': /* CUU cursor up */
  284.             dscursormove(CURSOR_UP, arg[0]);
  285.             break;
  286.  
  287.         case 'B': /* CUD cursor down */
  288.             dscursormove(CURSOR_DOWN, arg[0]);
  289.             break;
  290.  
  291.         case 'C': /* CUF cursor right/forward */
  292.             dscursormove(CURSOR_RIGHT, arg[0]);
  293.             break;
  294.  
  295.         case 'D': /* CUB cursor left/backward */
  296.             dscursormove(CURSOR_LEFT, arg[0]);
  297.             break;
  298.  
  299.         case 'H': case 'f': /* move cursor to specific position. CUP, HVP */
  300.             if (arg[0])  arg[0]--;
  301.             if (arg[1])  arg[1]--;
  302.             dscursorto(arg[1], arg[0]);
  303.             break;
  304.  
  305.         case 'J': /* ED clear to end of display. (erase in display) */
  306.             switch (arg[0]) {
  307.             case 0:
  308.                 dsfunction(ERASETO_EOS);
  309.                 break;
  310.  
  311.             case 1:
  312.                 dsfunction(ERASETO_SOS);
  313.                 break;
  314.  
  315.             case 2:
  316.                 dsclearscreen();
  317.                 break;
  318.             }
  319.             break;
  320.             
  321.         case 'K': /* EL clear to end of line. (erase in line) */
  322.             switch (arg[0]) {
  323.             case 0:
  324.                 dsfunction(ERASETO_EOL);
  325.                 break;
  326.  
  327.             case 1:
  328.                 dsfunction(ERASETO_SOL);
  329.                 break;
  330.  
  331.             case 2:
  332.                 dsfunction(ERASE_LINE);
  333.                 break;
  334.             }
  335.             break;
  336.  
  337.         case 'L': /* insert line VT102 */
  338.             dscursormove(INSERT_LINE, arg[0]);
  339.             break;
  340.  
  341.         case 'M': /* delete line VT102 */
  342.             dscursormove(DELETE_LINE, arg[0]);
  343.             break;
  344.  
  345.         case 'P': /* delete character VT102 */
  346.             if (!arg[0])
  347.             arg[0] = 1;
  348.             dsdelete(arg[0]);
  349.             break;
  350.  
  351.         case '@': /* ansi insert character */
  352.             dscursormove(INSERT_CHAR, arg[0]);
  353.             break;
  354.  
  355.         case 'c': /* DA Device Attributes request */
  356.             if (arg[0] == 0) {
  357.             (void) write_to_tty(VT100ATTRIBS,7);
  358.             }
  359.             break;
  360.  
  361.         case 'g': /* TBC tabulation clear */
  362.             dsgetcursor(&x, &y);
  363.             for (i=0; i<=curarg; i++) switch (arg[i]) {
  364.             case 0:
  365.                 dsfunction(CLEAR_TAB);
  366.                 break;
  367.  
  368.             case 3:
  369.                 dsfunction(CLEAR_ALL_TABS);
  370.             }
  371.             break;
  372.  
  373.         case 'h': /* SM set terminal mode */
  374.             for (i=0; i<=curarg; i++)
  375.             terminalMode(arg[i], private, 1);
  376.             break;
  377.  
  378.         case 'l': /* RM reset terminal mode */
  379.             for (i=0; i<=curarg; i++)
  380.             terminalMode(arg[i], private, 0);
  381.             break;
  382.             
  383.         case 'm': /* SGR styles (select graphic rendition) */
  384.             for (i=0; i<=curarg; i++)
  385.             vtstyle(arg[i]);
  386.             break;
  387.  
  388.         case 'n': /* DSR  Device status report */
  389.             for (i=0; i<=curarg; i++) switch (arg[i]) {
  390.             case 5:
  391.                 (void) write_to_tty("\033[0n",4);
  392.                 break;
  393.  
  394.             case 6: {
  395.                 char cursorpos[10];
  396.                 char *cpos;
  397.                 int tempx, tempy;
  398.  
  399.                 dsgetcursor(&tempx, &tempy);
  400.                 if (tempx == 0 && tempy == 0)
  401.                 (void) write_to_tty("\033[R",3);
  402.                 else {
  403.                 cursorpos[0] = '\033';
  404.                 cursorpos[1] = '[';
  405.                 (void) strcpy(cursorpos + 2, itos(tempy + 1));
  406.                 cpos = cursorpos + strlen(cursorpos);
  407.                 *cpos++ = ';';
  408.                 (void) strcpy(cpos, itos(tempx + 1));
  409.                 (void) strcat(cpos, "R");
  410.                 (void) write_to_tty(cursorpos, strlen(cursorpos));
  411.                 }
  412.                 break;
  413.                 }
  414.             }
  415.             break;
  416.  
  417.         case 'q': /* DECLL set LEDs on keyboard */
  418.             {
  419.             int leds = 0;
  420.  
  421.             for (i=0; i<=curarg; i++) {
  422.                 if (!arg[i])
  423.                     leds = 0;
  424.                 else if (arg[i] <= 4)
  425.                     leds |= 1 << (arg[i]-1);
  426.             }
  427.             dskeyboard(DS_LEDS, leds);
  428.             }
  429.             break;
  430.  
  431.         case 'r': /* DECSTBM set top and bottom margins (scrolling range) */
  432.             dssetscroll(arg[0],arg[1]);
  433.             break;
  434.  
  435.         case 'x': /* DECREQTPARM Request Terminal Parameters */
  436.             switch (arg[0]) {
  437.             case 0:
  438.                 sendgarbage=2;
  439.                 vtreport();
  440.                 break;
  441.  
  442.             case 1:
  443.                 sendgarbage=3;
  444.                 vtreport();
  445.                 break;
  446.             }
  447.             break;
  448.             
  449.         default:
  450.             break;
  451.         }
  452.         break;
  453.  
  454.     case 3: /* dec private codes for fonts */
  455.         switch(c) {
  456.         case '3':
  457.             (void) dsstyle(DWIDTHTOP);
  458.             break;
  459.  
  460.         case '4':
  461.             (void) dsstyle(DWIDTHBOT);
  462.             break;
  463.  
  464.         case '5':
  465.             (void) dsstyle(DWIDTH0);
  466.             break;
  467.  
  468.         case '6':
  469.             (void) dsstyle(DWIDTH1);
  470.             break;
  471.             
  472.         case '8':
  473.             dstestscreen();
  474.             break;
  475.         }
  476.         break;
  477.  
  478.     case 4: case 5: /* SCS: select character set: ESC( or ESC) */
  479.         switch (c) {
  480.         case 'A': case 'B': case '1': /* change to UK/US/other ROM set */
  481.             G[esc_mode - 4] = 0;
  482.             if (esc_mode - 4 == curset)
  483.             (void) dsstyle(ALTERNATE0);
  484.             break;
  485.  
  486.         case '0': case '2': /* change to graphic set/graphic ROM set */
  487.             G[esc_mode - 4] = 1;
  488.             if (esc_mode - 4 == curset)
  489.             (void) dsstyle(ALTERNATE1);
  490.             break;
  491.  
  492.         default:
  493.             esc_mode = 0;
  494.             return (1);
  495.         }
  496.         break;
  497.  
  498.     case 10: /* VT52 emulation -- ESC just hit */
  499.         switch (c) {
  500.         case 'A': /* cursor up */
  501.             dscursormove(CURSOR_UP, 1);
  502.             break;
  503.  
  504.         case 'B': /* cursor down */
  505.             dscursormove(CURSOR_DOWN, 1);
  506.             break;
  507.  
  508.         case 'C': /* cursor right */
  509.             dscursormove(CURSOR_RIGHT, 1);
  510.             break;
  511.  
  512.         case 'D': /* cursor left */
  513.             dscursormove(CURSOR_LEFT, 1);
  514.             break;
  515.  
  516.         case 'F': /* alternate characters */
  517.             (void) dsstyle(ALTERNATE1);
  518.             break;
  519.  
  520.         case 'G': /* standard characters */
  521.             (void) dsstyle(ALTERNATE0);
  522.             break;
  523.  
  524.         case 'H': /* home cursor */
  525.             dscursorto(0,0);
  526.             break;
  527.  
  528.         case 'I': /* reverse line feed */
  529.             dscursormove(REVERSE_INDEX,1);
  530.             break;
  531.  
  532.         case 'J': /* erase to end of screen */
  533.             dsfunction(ERASETO_EOS);
  534.             break;
  535.  
  536.         case 'K': /* erase to end of line */
  537.             dsfunction(ERASETO_EOL);
  538.             break;
  539.  
  540.         case 'Y': /* move cursor to specific position */
  541.             esc_mode = 11;
  542.             return (0);
  543.  
  544.         case 'Z': /* Identify terminal sequence */
  545.             (void) write_to_tty("\033/Z",3); /* VT100 emulating a VT52 */
  546.             break;
  547.  
  548.         case '<': /* switch to ANSI mode */
  549.             emulation = EMU_VT102;
  550.             break;
  551.         }
  552.         break;
  553.  
  554.     case 11:
  555.         arg[0] = (c&0x7f) - ' ';
  556.         esc_mode = 12;
  557.         return (0);
  558.  
  559.     case 12:
  560.         arg[1] = (c&0x7f) - ' ';
  561.         dscursorto(arg[1], arg[0]);
  562.         break;
  563.  
  564.     case 20: /* H19 emulation -- ESC just hit */
  565.         /* here is a list of unimplemented escapes:
  566.          * <   enter ansi mode
  567.          * [   enter hold screen mode (implemented as ansi codes)
  568.          * \   exit hold screen mode
  569.          * }   inhibit keyboard output
  570.          * {   enable keyboard output
  571.          * ]   Transmit 25th line
  572.          * #   Transmit page
  573.          * r   Set baud rate
  574.          */
  575.         switch (c) {
  576.         case 'A': /* HCUU: cursor up */
  577.             dscursormove(CURSOR_UP, 1);
  578.             break;
  579.  
  580.         case 'B': /* HCUD: cursor down */
  581.             dscursormove(CURSOR_DOWN, 1);
  582.             break;
  583.  
  584.         case 'C': /* HCUF: cursor right */
  585.             dscursormove(CURSOR_RIGHT, 1);
  586.             break;
  587.  
  588.         case 'D': /* HCUB: cursor left */
  589.             dscursormove(CURSOR_LEFT, 1);
  590.             break;
  591.  
  592.         case 'E': /* HCD: clear screen */
  593.             dsclearscreen();
  594.             break;
  595.  
  596.         case 'F': /* HEGM: alternate characters */
  597.             (void) dsstyle(ALTERNATE1);
  598.             break;
  599.  
  600.         case 'G': /* HXGM: standard characters */
  601.             (void) dsstyle(ALTERNATE0);
  602.             break;
  603.  
  604.         case 'H': /* HCUH: home cursor */
  605.             dscursorto(0,0);
  606.             break;
  607.  
  608.         case 'I': /* HRI: reverse line feed */
  609.             dscursormove(REVERSE_INDEX,1);
  610.             break;
  611.  
  612.         case 'J': /* HEOP: erase to end of screen */
  613.             dsfunction(ERASETO_EOS);
  614.             break;
  615.  
  616.         case 'K': /* HEOL: erase to end of line */
  617.             dsfunction(ERASETO_EOL);
  618.             break;
  619.  
  620.         case 'L': /* HIL: add new blank line */
  621.             dscursormove(INSERT_LINE,1);
  622.             break;
  623.  
  624.         case 'M': /* HDL: delete line */
  625.             dscursormove(DELETE_LINE,1);
  626.             break;
  627.  
  628.         case 'N': /* HDCH: delete character */
  629.             dsdelete(1);
  630.             break;
  631.  
  632.         case 'O': /* HERM: end insert mode */
  633.             dsfunction(INSERT_OFF);
  634.             break;
  635.  
  636.         case 'Y': /* HDCA: move cursor to specific position */
  637.             esc_mode = 11;
  638.             return (0);
  639.  
  640.         case 'Z': /* HID: Identify terminal sequence */
  641.             (void) write_to_tty("\033/K",3); /* can be vt52 */
  642.             break;
  643.  
  644.         case '@': /* HEIM: begin insert mode */
  645.             dsfunction(INSERT_ON);
  646.             break;
  647.  
  648.         case '[': /* ANSI controls for fun */
  649.             for (i=0; i<=MAXARG; i++)
  650.             arg[i]=0;
  651.             esc_mode = 2;
  652.             private = 0;
  653.             return (0);
  654.  
  655.         case '=': /* HAKM: enter alternate keypad mode */
  656.             dskeyboard(DS_KEYPADAPPMODE, 1);
  657.             break;
  658.  
  659.         case '>': /* HXAM: exit alternate keypad mode */
  660.             dskeyboard(DS_KEYPADAPPMODE, 0);
  661.  
  662.         case 'b': /* HBD: erase to start of screen */
  663.             dsfunction(ERASETO_SOS);
  664.             break;
  665.  
  666.         case 'j': /* HSCP: save cursor position */
  667.             dscursormove(SAVE_CURSOR,0);
  668.             break;
  669.  
  670.         case 'k': /* HRCP: restore cursor position */
  671.             dscursormove(RESTORE_CURSOR,0);
  672.             break;
  673.  
  674.         case 'l': /* HEL: erase the current line */
  675.             dsfunction(ERASE_LINE);
  676.             break;
  677.  
  678.         case 'n': { /* HCPR: report cursor position */
  679.             char cursorpos[10];
  680.             int tempx, tempy;
  681.  
  682.             dsgetcursor(&tempx, &tempy);
  683.             cursorpos[0] = '\033';
  684.             cursorpos[1] = 'Y';
  685.             cursorpos[2] = tempy + ' ';
  686.             cursorpos[3] = tempx + ' ';
  687.             cursorpos[4] = 0;
  688.             (void) write_to_tty(cursorpos, strlen(cursorpos));
  689.             break;
  690.             }
  691.  
  692.         case 'o': /* HEBL: erase to the beginning of the line */
  693.             dsfunction(ERASETO_SOL);
  694.             break;
  695.  
  696.         case 'p': /* HERV: begin stand out mode */
  697.             (void) dsstyle(INVERSE1);
  698.             break;
  699.  
  700.         case 'q': /* HXRV: end stand out mode */
  701.             (void) dsstyle(INVERSE0);
  702.             break;
  703.  
  704.         case 't': /* HEKS: enter shifted keypad mode */
  705.             dskeyboard(DS_KEYPADMODE, KEYPAD_H19S);
  706.             break;
  707.  
  708.         case 'u': /* HXKS: exit shifted keypad mode */
  709.             dskeyboard(DS_KEYPADMODE, KEYPAD_H19);
  710.             break;
  711.  
  712.         case 'v': /* HEWA: wrap mode on */
  713.             dsfunction(WRAP_ON);
  714.             break;
  715.  
  716.         case 'w': /* HXWA: wrap mode off */
  717.             dsfunction(WRAP_OFF);
  718.             break;
  719.  
  720.         case 'x': /* HSM: set mode */
  721.             esc_mode = 21;
  722.             return (0);
  723.  
  724.         case 'y': /* HRM: reset mode */
  725.             esc_mode = 22;
  726.             return (0);
  727.  
  728.         case 'z': /* HRAM: reset to power-up config */
  729.             dsfunction(RESET_DISPLAY);
  730.             break;
  731.         }
  732.         break;
  733.  
  734.     case 21: case 22:
  735.         terminalMode(c - '0', 2, esc_mode == 21);
  736.         break;
  737.     }
  738.  
  739.     return (esc_mode = 0);
  740. }
  741.  
  742. /* output characters to display
  743.  * the buffer text must have at least one extra byte after text+count
  744.  */
  745. #define    FLUSHBUF    if (front < text) { *text = 0; dsputs(front); } front = text + 1;
  746. void
  747. termout(text, count)
  748. char *text;
  749. int count;
  750. {
  751.     static char buffer[MAXTERMBUF];
  752.     char    c;
  753.     char    *textend = text + count;
  754.     char    *bp = buffer, *bpend = buffer + MAXTERMBUF - 1;
  755.     char    *front;
  756.  
  757.     dscursoroff();
  758.     for (front = text; text < textend; text++) {
  759.     if ((c = *text ) >= ' ' || (c < 0)) {
  760.         if(!pass8) *text &= 127;
  761.         if (c == DEL) {
  762.         vt100_yucky_wrap_mode = 0;
  763.         FLUSHBUF;
  764.         continue;
  765.         } else if (esc_mode) {
  766.         vt100_yucky_wrap_mode = 0;
  767.         if (!decode_escapes(c))
  768.             front++;
  769.         } 
  770.         continue;
  771.     } else {
  772.         vt100_yucky_wrap_mode = 0;
  773.         FLUSHBUF;
  774.         switch (c) {
  775.         case CTRL('G'):
  776.             if (bell_type & 1)
  777.             dsinvert(VISUAL_BELL);
  778.             if (bell_type & 2)
  779.             audiobell();
  780.             if (bell_type & 4)
  781.                 DisplayBeep(0);
  782.             break;
  783.         
  784.         case CTRL('H'): /* cursor left */
  785.             dscursormove(CURSOR_LEFT, 1);
  786.             break;
  787.  
  788.         case '\t':    /* tab */
  789.             dscursormove(TAB_STOP,0);
  790.             break;
  791.  
  792.         case CTRL('L'): /* clear screen on h19 */
  793.             if (emulation == EMU_H19) {
  794.             dsclearscreen();
  795.             break;
  796.             }        /* fall through */
  797.         case CTRL('J'):
  798.             if (ansi_LNM && c == CTRL('J')) {
  799.             dscursormove(NEXT_LINE, 1);
  800.             break;
  801.             }        /* fall through */
  802.         case CTRL('K'): /* cursor down w/ scroll */
  803.             if (!dscheckdown()) {
  804.             register char   *scan;
  805.             register int    retcnt = 1;
  806.  
  807.             for (scan = text+1; scan < textend && *scan != ESC; scan++)
  808.                 if (*scan == CTRL('J') || *scan == CTRL('K'))
  809.                 retcnt++;
  810.             dscursormove(DOWN1_AND_SCROLL, retcnt);
  811.             }
  812.             break;
  813.  
  814.         case CTRL('M'): /* CR / newline */
  815.             dscursormove(BEGIN_LINE, 0);
  816.             break;
  817.  
  818.         case CTRL('N'): /* SI -- shift in alternate */
  819.             curset=1;
  820.             if (G[curset] || emulation == EMU_VT52)
  821.             (void) dsstyle(ALTERNATE1);
  822.             else
  823.             (void) dsstyle(ALTERNATE0);
  824.             break;
  825.  
  826.         case CTRL('O'): /* SO -- shift out alternate */
  827.             curset=0;
  828.             if (G[curset] && emulation == EMU_VT102)
  829.             (void) dsstyle(ALTERNATE1);
  830.             else
  831.             (void) dsstyle(ALTERNATE0);
  832.             break;
  833.  
  834.         case CTRL('X'): case CTRL('Z'): /* cancel escape sequence */
  835.             esc_mode = 0;
  836.             break;
  837.  
  838.         case ESC:    /* escape key */
  839.             switch (emulation) {
  840.             case EMU_VT102:
  841.                 esc_mode = 1;
  842.                 break;
  843.  
  844.             case EMU_VT52:
  845.                 esc_mode = 10;
  846.                 break;
  847.  
  848.             case EMU_H19:
  849.                 esc_mode = 20;
  850.                 break;
  851.             }
  852.             curarg = 0;
  853.             break;
  854.         }
  855.     }
  856.     }
  857.     FLUSHBUF;
  858.     dscursoron();
  859. }
  860.  
  861. /* send a DECREPTPARM report
  862.  */
  863. void
  864. vtreport()
  865. {
  866.     char report[20];
  867.     
  868.     (void) strcpy(report, "\033[0;1;1;88;88;1;0x");
  869.     report[2] = '0' + sendgarbage;
  870.     (void) write_to_tty(report, strlen(report));
  871. }
  872.  
  873. /* arguments for the style commands: SGR -- ESC [ param ; .. ; m
  874.  */
  875. void
  876. vtstyle(c)
  877. int c;
  878. {
  879.     switch (c) {
  880.     case 1:
  881.         (void) dsstyle(BOLD1);
  882.         break;
  883.     case 21:
  884.         (void) dsstyle(BOLD0);
  885.         break;
  886.     case 3:
  887.         (void) dsstyle(ITALIC1);
  888.         break;
  889.     case 23:
  890.         (void) dsstyle(ITALIC0);
  891.         break;
  892.     case 4:
  893.         (void) dsstyle(UNDERLINE1);
  894.         break;
  895.     case 24:
  896.         (void) dsstyle(UNDERLINE0);
  897.         break;
  898.     case 5:
  899.         (void) dsstyle(BLINK1);
  900.         break;
  901.     case 25:
  902.         (void) dsstyle(BLINK0);
  903.         break;
  904.     case 7:
  905.         (void) dsstyle(INVERSE1);
  906.         break;
  907.     case 27:
  908.         (void) dsstyle(INVERSE0);
  909.         break;
  910.     case 8:
  911.         (void) dsstyle(BLANK1);
  912.         break;
  913.     case 28:
  914.         (void) dsstyle(BLANK0);
  915.         break;
  916.     case 0:
  917.         (void) dsstyle(STYLESOFF);
  918.         if (G[curset])
  919.         (void) dsstyle(ALTERNATE1);
  920.         else
  921.         (void) dsstyle(ALTERNATE0);
  922.         break;
  923.     case 10:
  924.         (void) dsstyle(ALTERNATE1);
  925.         break;
  926.     case 11:
  927.         (void) dsstyle(ALTERNATE0);
  928.         break;
  929.     }
  930. }
  931.  
  932. #if 0
  933. /* set up termcap and termtype
  934.  */
  935. char *gettermcap()
  936. {
  937.     switch (emulation) {
  938.     case EMU_H19:
  939.         return (h19termcap);
  940.     case EMU_VT52:
  941.         return (vt52termcap);
  942.     default:
  943.         return (termcap);
  944.     }
  945. }
  946. char *gettermtype()
  947. {
  948.     switch (emulation) {
  949.     case EMU_H19:
  950.         return (h19termtype);
  951.     case EMU_VT52:
  952.         return (vt52termtype);
  953.     default:
  954.         return (termtype);
  955.     }
  956. }
  957. #endif
  958.